/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package rekeningrijden;

import auto.BoordComputer;
import auto.BoordComputerImpl;
import auto.GPS;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.border.TitledBorder;
import rekeningrijdenserver.RekeningRijdenServer;
import tijdserver.TijdServer;

/**
 *
 * @author Jonas
 */
public class BoordComputerGUI extends JFrame{
    TijdServer tijdServer;
    RekeningRijdenServer rekeningRijdenServer;
    BoordComputer boordComputer;
    GPS gps;

    public BoordComputerGUI(TijdServer tijdServer, RekeningRijdenServer rekeningRijdenServer, BoordComputer boordComputer, GPS gps) {
        this.tijdServer = tijdServer;
        this.rekeningRijdenServer = rekeningRijdenServer;
        this.boordComputer = boordComputer;
        this.gps = gps;
    }

    public void createAndShowGUI(){
        // setup frame
        this.setTitle("Rekeningrijden Simulator");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.getContentPane().setLayout(new BorderLayout());

        // Simulation interface
        JLabel systemStatus = new JLabel("Opstarten van de simulator ...");
        systemStatus.setBorder(new TitledBorder("Status simulator"));
        if(boordComputer instanceof BoordComputerImpl)
            ((BoordComputerImpl)boordComputer).setLocationListener(systemStatus);
        systemStatus.setFont(new Font(null, Font.ITALIC, 12));
        this.getContentPane().add(systemStatus,BorderLayout.PAGE_END);

        // setup BC-interface
        JPanel cp = new JPanel();
        cp.setBorder(new TitledBorder("Boordcomputer-interface"));
        cp.setLayout(new FlowLayout());
        this.getContentPane().add(cp,BorderLayout.CENTER);


        // BC: buttons and labels
        JToggleButton engineButton = new JToggleButton();
        engineButton.setEnabled(false);
        engineButton.setIcon(new ImageIcon("imgs/engineNotRunning.gif"));
        engineButton.setSelectedIcon(new ImageIcon("imgs/engineRunning.gif"));
        engineButton.setPreferredSize(new Dimension(210,160));
        JLabel engineStatus = new JLabel("Status: Motor draait niet");
        JToggleButton GPSButton = new JToggleButton();
        GPSButton.setSelectedIcon(new ImageIcon("imgs/gpsAtt.gif"));
        GPSButton.setIcon(new ImageIcon("imgs/gpsDet.gif"));
        GPSButton.setPreferredSize(new Dimension(210,160));
        GPSButton.setEnabled(false);
        JLabel GPSStatus = new JLabel("Status: geen GPS aanwezig");

        engineButton.addActionListener(new EngineButtonListener(boordComputer, engineButton, GPSButton, engineStatus,GPSStatus,systemStatus,this));
        cp.add(engineButton);
        //cp.add(engineStatus);

        GPSButton.addActionListener(new GPSButtonListener(boordComputer, gps, GPSButton, engineStatus, GPSStatus,systemStatus));
        cp.add(GPSButton);
        //cp.add(GPSStatus);


        // BC: menus
        JMenuBar menuBar ;
        JMenu fileMenu = new JMenu("Bestand");
        JMenu keuringMenu = new JMenu("Keuring");
        JMenu helpMenu = new JMenu("Help");
        JMenu subMenu;
        JMenuItem menuItem;

        menuBar = new JMenuBar();
        this.setJMenuBar(menuBar);
        menuBar.add(fileMenu);
        menuBar.add(keuringMenu);
        menuBar.add(helpMenu);

        subMenu = new JMenu("GPS Data");
        fileMenu.add(subMenu);
        menuItem = new JMenuItem("Open gpsData.txt");
        menuItem.setAccelerator(KeyStroke.getKeyStroke("control G"));
        subMenu.add(menuItem);
        menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                try {
                        Desktop.getDesktop().open(new File("gpsData.txt"));
                } catch (IOException ex) {System.err.println(ex);}
            }
        });
        menuItem = new JMenuItem("Decrypteer gpsData.txt");
        menuItem.setAccelerator(KeyStroke.getKeyStroke("control alt G"));
        subMenu.add(menuItem);
        menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                try {
                    Desktop.getDesktop().open(new File("decryption.bat"));
                } catch (IOException ex) {
                    System.err.println(ex);
                }
            }
        });
        menuItem = new JMenuItem("Open serverData.txt");
        menuItem.setAccelerator(KeyStroke.getKeyStroke("control S"));
        fileMenu.add(menuItem);
        menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                try {
                        Desktop.getDesktop().open(new File("serverData.txt"));
                } catch (IOException ex) {System.err.println(ex);}
            }
        });

        menuItem = new JMenuItem("Beëindigen");
        menuItem.setAccelerator(KeyStroke.getKeyStroke("ESCAPE"));
        fileMenu.add(menuItem);
        menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        menuItem = new JMenuItem("Integriteitscontrole");
        keuringMenu.add(menuItem);
        menuItem.addActionListener(new IntegrityChecker(boordComputer, rekeningRijdenServer));
        
        menuItem = new JMenuItem("Help");
        menuItem.setAccelerator(KeyStroke.getKeyStroke("F1"));
        helpMenu.add(menuItem);
        menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                try {
                        Desktop.getDesktop().open(new File("help.html"));
                } catch (IOException ex) {System.err.println(ex);}
            }
        });

        menuItem = new JMenuItem("About");
        helpMenu.add(menuItem);
        menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null,"Deze simulator werd geschreven door: \n>Fréderic Godin\n>Jonas El Sayeh Khalil\n>Roel Verschaeren\n>Sam De Roeck","About...",JOptionPane.INFORMATION_MESSAGE);
            }
        });

        
        this.setSize(500,300);
        this.setResizable(false);
        this.setVisible(true);

        try {
            if(!((new File("./bestuurderPrivate.key")).exists()
                    && (new File("./bestuurderPublic.key")).exists()
                    && (new File("./bestuurderPrivate.key")).exists()
                    && (new File("./bestuurderPrivate.key")).exists())){
                systemStatus.setText("Generatie private/publieke/geheime sleutel van de bestuurder");
                auto.keyGenerator.main(null);
            }
            if(!((new File("./RRSPrivate.key")).exists() && (new File("./RRSPublic.key")).exists())){
                systemStatus.setText("Generatie private/publieke sleutel van de rekeningrijdenserver");
                rekeningrijdenserver.keyGenerator.main(null);
            }
            if(!((new File("./TSPrivate.key")).exists() && (new File("./TSPublic.key")).exists())){
                systemStatus.setText("Generatie private/publieke sleutel van de tijdserver");
                tijdserver.keyGenerator.main(null);
            }
        } catch (Exception e) {
        }

        systemStatus.setText("Wagen staat stil, geen gps aanwezig");
        engineButton.setEnabled(true);
        GPSButton.setEnabled(true);
    }
}

class EngineButtonListener implements ActionListener{
    BoordComputer boordComputer;
    JToggleButton engine;
    JToggleButton gps;
    JLabel engineFeedback;
    JLabel gpsFeedback;
    JLabel simStatus;
    Frame frame;

    public EngineButtonListener(BoordComputer boordComputer, JToggleButton engine, JToggleButton gps, JLabel engineFeedback, JLabel gpsFeedback,JLabel simStatus,Frame GUI) {
        this.boordComputer = boordComputer;
        this.engine = engine;
        this.gps = gps;
        this.engineFeedback = engineFeedback;
        this.gpsFeedback = gpsFeedback;
        this.simStatus = simStatus;
        frame = GUI;
    }

    public void actionPerformed(ActionEvent e) {
        if(engine.isSelected()){
            boolean worked = boordComputer.startEngine();
            if(!worked){
                JOptionPane.showMessageDialog (frame ,"Rijden zonder GPS is onmogelijk" ,"GPS ontbreekt ..." ,JOptionPane.ERROR_MESSAGE) ;
                engine.setSelected(false);
                engineFeedback.setText("Status: Motor draait niet");
            }
            else{
                engineFeedback.setText("Status: Motor draait");
                gpsFeedback.setText("Status: GPS vastgeklikt");
                simStatus.setText("Wagen rijdt");
                gps.setEnabled(false);
            }
        }
        else{
            boordComputer.stopEngine();
            gps.setEnabled(true);
            engineFeedback.setText("Status: Motor draait niet");
            gpsFeedback.setText("Status: GPS losgeklikt maar nog aanwezig");
        }
    }
}

class GPSButtonListener implements ActionListener{
    BoordComputer boordComputer;
    GPS gps;
    JToggleButton gpsButton;
    JLabel engineFeedback;
    JLabel gpsFeedback;
    JLabel simStatus;

    public GPSButtonListener(BoordComputer boordComputer, GPS gps, JToggleButton gpsButton, JLabel engineFeedback, JLabel gpsFeedback, JLabel simStatus) {
        this.boordComputer = boordComputer;
        this.gps = gps;
        this.gpsButton = gpsButton;
        this.engineFeedback = engineFeedback;
        this.gpsFeedback = gpsFeedback;
        this.simStatus = simStatus;
    }

    public void actionPerformed(ActionEvent e) {
        if(gpsButton.isSelected()){
            boordComputer.attachGPS(gps);
            gpsFeedback.setText("Status: GPS aanwezig");
            simStatus.setText("Wagen staat stil, gps aanwezig");
        }
        else{
            boordComputer.detachGPS();
            gpsFeedback.setText("Status: geen GPS aanwezig");
            simStatus.setText("Wagen staat stil, geen gps aanwezig");
        }
    }
}

class IntegrityChecker implements ActionListener{
    private BoordComputer bc;
    private RekeningRijdenServer rrs;

    public IntegrityChecker(BoordComputer bc,RekeningRijdenServer rrs) {
        this.bc = bc;
        this.rrs = rrs;
    }

    public void actionPerformed(ActionEvent e) {
        boolean ok = bc.checkWithServer(rrs);
        if(ok)
            JOptionPane.showMessageDialog(null,"Data in server en op boordcomputer komen overeen","Integriteitscontrole",JOptionPane.INFORMATION_MESSAGE);
        else
            JOptionPane.showMessageDialog (null ,"Data in de server en op boordcomputer komen niet overeen!" ,"Integriteitscontrole" ,JOptionPane.ERROR_MESSAGE) ;
    }
}